package com.hyt.it.ogt.pj.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;

import com.hyt.html2file.enums.HtmlToXEnum;
import com.hyt.it.ogt.pj.enums.SubjectiveItemTypeEnum;
import com.hyt.it.ogt.common.config.GlobalConfig;
import com.hyt.it.ogt.pj.enums.ItemType;
import com.hyt.it.ogt.pj.model.vo.PaperItemVo;
import com.hyt.it.ogt.pj.service.IImageService;
import freemarker.template.Template;
import gui.ava.html.parser.HtmlParser;
import gui.ava.html.parser.HtmlParserImpl;
import gui.ava.html.renderer.ImageRenderer;
import gui.ava.html.renderer.ImageRendererImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Description:
 * 图片处理服务
 *
 * @author yaoj
 * @version 1.0
 * @copyright Copyright (c) hyt
 * @since 2022/4/5
 */
@Slf4j
@RefreshScope
@Service
public class ImageServiceImpl implements IImageService {

    @Value("${exchange.imgwitd:700}")
    private int imgWith;
    @Value("${exchange.showstem:false}")
    private boolean showstem;
    @Value("${exchange.imgcompress:true}")
    private boolean imgcompress;
    @Value("${exchange.imgcompressratio:3}")
    private int imgcompressratio;
    @Value("${exchange.englishwith:60}")
    private int englishwith;
    @Value("${exchange.chinesehwith:34}")
    private int chinesehwith;
    @Resource
    GlobalConfig globalConfig;

    String regex = "[a-zA-Z0-9 ，。？：；‘’！“”—……、（）【】《》,.?:;'!]+";


    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @Override
    public List<PaperItemVo> getImagesByPaper(List<PaperItemVo> paperItemVos) throws Exception {
        //去除样式问题
        fixHtml(paperItemVos);

        for (PaperItemVo paperItemVo : paperItemVos) {
            Template template = null;
            if (SubjectiveItemTypeEnum.compound.getCode().equals(paperItemVo.getItemType())) {
                try {
                    template = freeMarkerConfigurer.getConfiguration().getTemplate(ItemType.COMPOUND.getFileName());
                } catch (Exception e) {
                    log.error("# 生成模板异常", e);
                    throw new RuntimeException("文件处理错误");
                }
                // 复合题下存在有图片答题的情况
                if (CollectionUtils.isNotEmpty(paperItemVo.getChildren())) {
                    for (PaperItemVo child : paperItemVo.getChildren()) {
                        if (SubjectiveItemTypeEnum.picture_answer.getCode().equals(child.getItemType())) {
                            //获取考生的答题图片放入child里面
                            List<String> anwsers = StrUtil.split(child.getStudentAnswer(), ",");
                            List<PaperItemVo> anwserList = anwsers.stream()
                                    .map(anwser -> {
                                        PaperItemVo paperItemVo1 = new PaperItemVo();
                                        paperItemVo1.setStudentAnswer(anwser + "?x-image-process=image/quality,q_" + globalConfig.getQuality());
                                        return paperItemVo1;
                                    }).collect(Collectors.toList());
                            child.setChildren(anwserList);
                        }
                    }
                }
                paperItemVo.setAnswerImgFile(getImagePath(template, paperItemVo, showstem));
            } else if (SubjectiveItemTypeEnum.fill_in_blanks.getCode().equals(paperItemVo.getItemType())) {
                //填充模板
                try {
                    template = freeMarkerConfigurer.getConfiguration().getTemplate(ItemType.FILL_IN_BLANKS.getFileName());
                } catch (Exception e) {
                    log.error("# 生成模板异常", e);
                    throw new RuntimeException("文件处理错误");
                }
                paperItemVo.setAnswerImgFile(getImagePath(template, paperItemVo, showstem));
            } else if (SubjectiveItemTypeEnum.short_answer.getCode().equals(paperItemVo.getItemType())) {
                //填充模板
                try {
                    template = freeMarkerConfigurer.getConfiguration().getTemplate(ItemType.SHORT_ANSWER.getFileName());
                } catch (Exception e) {
                    log.error("# 生成模板异常", e);
                    throw new RuntimeException("文件处理错误");
                }
                paperItemVo.setAnswerImgFile(getImagePath(template, paperItemVo, showstem));
            } else if (SubjectiveItemTypeEnum.picture_answer.getCode().equals(paperItemVo.getItemType())) {
                try {
                    template = freeMarkerConfigurer.getConfiguration().getTemplate(ItemType.PICTURE_ANSWER.getFileName());
                } catch (Exception e) {
                    log.error("# 生成模板异常", e);
                    throw new RuntimeException("文件处理错误");
                }
                //获取考生的答题图片放入child里面
                List<String> anwsers = StrUtil.split(paperItemVo.getStudentAnswer(), ",");
                List<PaperItemVo> anwserList = anwsers.stream()
                        .map(anwser -> {
                            PaperItemVo paperItemVo1 = new PaperItemVo();
                            paperItemVo1.setStudentAnswer(anwser + "?x-image-process=image/quality,q_" + globalConfig.getQuality());
                            return paperItemVo1;
                        }).collect(Collectors.toList());
                paperItemVo.setChildren(anwserList);
                paperItemVo.setAnswerImgFile(getImagePath(template, paperItemVo, showstem));
            }

        }
        return paperItemVos;
    }

    /**
     * 处理富文本的问题
     *
     * @param paperItemVos
     */
    private void fixHtml(List<PaperItemVo> paperItemVos) {
        for (PaperItemVo paperItemVo : paperItemVos) {
            if (StringUtils.isNotBlank(paperItemVo.getItemStem())) {
                paperItemVo.setItemStem(removeContentStyle(paperItemVo.getItemStem()));
            }
            if (StringUtils.isNotBlank(paperItemVo.getStudentAnswer())) {
                paperItemVo.setStudentAnswer(removeContentStyle(paperItemVo.getStudentAnswer()));
            }
            if (paperItemVo.getItemStem() != null) {
                paperItemVo.setItemStem(paperItemVo.getItemStem());
            }
            if (paperItemVo.getChildren() != null && paperItemVo.getChildren().size() > 0) {
                fixHtml(paperItemVo.getChildren());
            }

        }
    }

    /**
     * 清除style中不支持的样式
     *
     * @param content 公告内容
     * @return 字符串结果集
     */
    public static String removeContentStyle(String content) {
        String regEx2 = "font-family:(.*?);";
        Pattern p2 = Pattern.compile(regEx2);
        Matcher m2 = p2.matcher(content);
        if (m2.find()) {
            content = m2.replaceAll("");
        }
        return content;
    }

    /**
     * 获取图片流根据模板
     *
     * @param template
     * @return
     */
    public BufferedImage getBufferedImage(Template template, PaperItemVo paperItemVo) {
        Map<String, Object> map = new HashMap<>();
        map.put("itemStem", paperItemVo.getItemStem());
        map.put("studentAnswer", paperItemVo.getStudentAnswer());
        map.put("children", paperItemVo.getChildren());
        String templateHtml = null;
        BufferedImage newBufferedImage = null;
        try {
            templateHtml = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("文件处理错误");
        }
        //将页面转换为图片
        HtmlParser htmlParser = new HtmlParserImpl();
        htmlParser.loadHtml(templateHtml);
        // html 是我的html代码
        ImageRenderer imageRenderer = new ImageRendererImpl(htmlParser);
        //图片宽度
        imageRenderer.setWidth(imgWith);

        BufferedImage bufferedImage = imageRenderer.getBufferedImage();
        log.debug("宽度是：" + imageRenderer.getHeight());
        newBufferedImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
        // TYPE_INT_RGB:创建一个RBG图像，24位深度，成功将32位图转化成24位
        newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null);
        return newBufferedImage;
    }

    /**
     * 获取图片流根据模板
     *
     * @param template
     * @return
     */
    public File getImagePath(Template template, PaperItemVo paperItemVo, boolean showstem) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("itemStem", paperItemVo.getItemStem());
        map.put("studentAnswer", paperItemVo.getStudentAnswer());
        map.put("children", paperItemVo.getChildren());
        map.put("showstem", showstem);
        map.put("anwserpicterwith", globalConfig.getAnwserpicterwith());
        String templateHtml = null;
        try {
            templateHtml = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        } catch (Exception e) {
            log.error("# 生成模板HTML文件异常", e);
            throw new RuntimeException("文件处理错误");
        }

        // 使用WkHtmlToImage进行生成图片
        if (globalConfig.getUseWkToImage()) {
            File templateFile = FileUtil.writeUtf8String(templateHtml, FileUtil.createTempFile(".html", Boolean.TRUE));
            templateFile.deleteOnExit();
            return HtmlToXEnum.IMAGE.execute(templateFile.getPath());
        }
        
        HtmlParser htmlParser = new HtmlParserImpl();
        try {
            htmlParser.loadHtml(templateHtml);
        } catch (Exception e) {
            log.error("# 模板HTML解析器异常", e);
            throw new RuntimeException("加载html错误。。。");
        }

        //将页面转换为图片
        // html 是我的html代码
        ImageRenderer imageRenderer = new ImageRendererImpl(htmlParser);
        //图片宽度
        imageRenderer.setWidth(imgWith);
        File imgFile = FileUtil.createTempFile(".png", Boolean.TRUE);
        imgFile.deleteOnExit();
        // 图片落盘
        imageRenderer.saveImage(imgFile);
        return imgFile;
    }


    /**
     * 给定一个长字符串内容，返回一个数组
     *
     * @param content 所有的内容
     * @param count   需要每段截取的长度
     * @return 所有分段的数组list
     */
    public static List<String> getListFromContent(String content, int count) {
        if (content == null || content.length() < 1) {
            return null;
        }
        List<String> list = new ArrayList<String>();
        // 获取String的总长度
        int contentLength = content.length();
        if (contentLength < count) {
            list.add(content);
        } else {
            int begin = 0;
            // 获取需要切割多少段
            int cutCount = contentLength / count;
            int cutCounts = contentLength % count;
            // 获取切割段的长度
            if (cutCounts != 0) {
                cutCount++;
            }
            for (int i = 1; i <= cutCount; i++) {
                String temp;
                // 不是最后一段
                if (i != cutCount) {
                    temp = content.substring(begin, count * i);
                } else {
                    temp = content.substring(begin, contentLength);
                }
                begin = count * i;
                list.add(temp);
            }
        }
        return list;
    }

}
